import base64
import json
import yaml
from flask import request, g
from flask_restful import abort
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from itsdangerous import BadSignature, SignatureExpired

# 项目key
import pyodbc

import time
from apps.dbConnect.dbCurd import dbCurdD
from apps.ext import cache
from comm.dateTime import nowDay

from comm.ext import sqlalchemyDataBase
import os

from comm.privateKey import jieMi, machineCode

# from comm.privateKey import privateKeyData
# from comm.dateTime import nowDay

SECRET_KEY = 'abcdefghijklmm'

def openDbBase():

    file_path = 'config.yaml'
    if os.path.isfile(file_path):
        with open(file_path, 'r', encoding='utf-8') as file:
            config = yaml.safe_load(file)
            file.close()
        if config.get('privateKey',"") == "":
            raise ValueError("请配置秘钥privateKey")
        privateKey,err = jieMi(config['privateKey'])
        if err != None:
            raise ValueError(err)
        if privateKey['key'] != machineCode():
            raise ValueError("识别码非此台主机:" + machineCode())
        if nowDay() > privateKey['validity']:
            raise ValueError("系统过期请联系管理员有效期为:" + privateKey['validity'])
        return config

    file_path = 'db_base.json'
    if os.path.isfile(file_path):
        with open(file_path, 'r', encoding='utf-8') as json_data:
            config = json.load(json_data)
            json_data.close()
        return config

    raise ValueError("配置文件不存在")

class Config:
    """
    TYPE:MYSQL 表身mysql数据库；MSSQL表示sql serve
    """
    dbproconfig = openDbBase()
    print('数据库连接地址',sqlalchemyDataBase(dbproconfig))
    SQLALCHEMY_DATABASE_URI = sqlalchemyDataBase(dbproconfig)
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_ECHO = False
    TESTING = False
    DEBUG = False
    VERIFYBOARD = False

# 生成token, 有效时间为600min
def generate_auth_token(data, expiration=60*60*24*7):
    # 第一个参数是内部私钥
    # 第二个参数是有效期（秒）
    s = Serializer(SECRET_KEY, expires_in=expiration)
    return s.dumps(data)
# 解析token
def verify_auth_token(token):
    s = Serializer(SECRET_KEY)
    # token正确
    try:
        data = s.loads(token)
        return data
    # token过期
    except SignatureExpired:
        abort(401,msg='带签证token过期')
        # return None
    # token错误
    except BadSignature:
        abort(401, msg='带签证token错误')
        # return None
# 登录验证装饰器
def login_required(fun):

    def wrapper(*args,**kwargs):
        token = request.headers.get("token",None)
        print('进入登录验证')
        if not token:
            abort(401,msg="请携带签证token")
        if token is None:
            abort(401, msg="请携带签证token")
        user = verify_auth_token(token)
        g.userId = user['userId']
        g.token = token
        return fun(*args,**kwargs)
    return wrapper

# 登录校验装饰
def login_required_api(fun):

    def wrapper(*args,**kwargs):
        token = request.headers.get("token",None)
        # print('进入登录验证')
        if not token:
            abort(401,msg="请携带签证token")
        if token is None:
            abort(401, msg="请携带签证token")
        token = request.headers.get("token", None)
        g.token = token
        return fun(*args,**kwargs)
    return wrapper


# # sunlike Api登录校验装饰
# def login_required(fun):
#
#     def wrapper(*args,**kwargs):
#         token = request.headers.get("token",None)
#         print('进入登录验证')
#         if not token:
#             abort(401,msg="请携带签证token")
#         if token is None:
#             abort(401, msg="请携带签证token")
#         return fun(*args,**kwargs)
#     return wrapper

# 接口限流装饰器
def current_limiting(second):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print('进入限流')
            token = request.headers.get("token", None)
            timestamp1 = time.time()
            if token is None:
                abort(401, msg="请携带签证token")
            else:
                timestamp2 = cache.get(token)
                if timestamp2 is None:
                    cache.set(token, timestamp1, timeout=second)
                    return func(*args, **kwargs)
                cache.set(token, timestamp1, timeout=second)
                if  timestamp2:
                    abort(401, msg="操作频繁请稍后重试")
                return func(*args, **kwargs)
        return wrapper
    return decorator

# def current_limiting(*args,**kwargs):
#     def func(function_name):
#         def func_in(*args,**kwargs):
#             print('--记录日志-args=%s'%args)
#         return func_in(*args,**kwargs)
#     return func


def get_user(usr, pwd):
    sql = """select id,username,password from xt_users where username=:id or id=:id"""
    data, err = dbCurdD.dbOneJson(sql,{'id':usr})
    print(data)
    if err !=None:
        return {'login_status': False, 'msg': repr(err)}
    if data is None:
        print('账号不存在')
        return {'login_status':False,'msg':'账号不存在'}
    if data == {}:
        print('账号不存在')
        return {'login_status':False,'msg':'账号不存在'}
    try:
        password = base64.b64decode(data['password']).decode('utf-8')
    except:
        return {'login_status': False, 'msg': '密码解析失败'}
    if pwd !=password:
        print(password)
        return {'login_status': False, 'msg': '密码错误'}
    return {'login_status': True, 'msg': 'OK','username':data['username'],'id':data['id']}

def orgCodeConfig():
    config_data = openDbBase()
    sql1 = "select id,code from Base_Organization where code=:code"
    data,err = dbCurdD.dbOneJson(sql1,{"code":config_data['ORGCODE']})
    return data,err
class ProCongif(Config):
    DEBUG = True
envs = {
    "pro":ProCongif,
}

